﻿using System;
using System.Collections.Generic;
using System.Text;
using MirrorDrive.Operations;
using MirrorDrive.Server.Authorization;
using RemoteCode;
using SecureConnection;

namespace MirrorDrive.Server
{
    public class MirrorClient
    {
        private Nexum _nexum;
        private MirrorServer _server;
        private bool _disposed = false;
        private object _syncLock = new object();

        public int Id { get; private set; }
        public string Username { get; private set; }
        public string Password { get; private set; }

        public bool Authorized { get; private set; }
        public AuthorizationResponse AuthResponse { get; private set; }


        internal MirrorClient(MirrorServer server, Nexum nexum)
        {
            this.Id = nexum.SharedId;
            this.Authorized = false;

            _nexum = nexum;
            _server = server;

            Initialize();
        }

        private void Initialize()
        {
            _nexum.OnDisconnect += _nexum_OnDisconnect;

            _nexum.Wait("InfoShared", 15000);

            string[] info = _nexum.GetVariable("User Information").Get<string[]>();

            this.Username = info[0];
            this.Password = info[1];

            AuthResponse = _server._authorizationBase.Authorize(Username, Password);

            Authorized = AuthResponse.Authorized;
            if (!Authorized)
            {
                _nexum.Dispose();
                return;
            }

            _nexum.ShareInitializedClass("Operations", new ServerOperations(new MirrorDriveOperations(AuthResponse.AllowedPath, AuthResponse.Access)));
            _nexum.Pulse("Done", timeOut: 15000);

            _server.AddClient(this);
        }

        private void _nexum_OnDisconnect(Nexum n, CloseReason reason)
        {
            Close();
        }

        public void Close()
        {
            lock (_syncLock)
            {
                if (_disposed)
                    return;
                _disposed = true;

                _server.RemoveClient(this);

                _nexum.Dispose();
            }
        }
    }
}
